/******************************************************************************\
 * Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik
 * Copyright (c) 2001
 *
 * Author(s):
 *	Volker Fischer
 *
 * Description:
 *	
 *
 ******************************************************************************
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later 
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
\******************************************************************************/

#include <qlistview.h>
#include <qpixmap.h>
#include <qbuttongroup.h>
#include <qradiobutton.h>
#include <qtimer.h>
#include <qmessagebox.h>
#include <qcombobox.h>
#include <qurloperator.h>
#include <qnetworkprotocol.h>
#include <qdir.h>
#include <qmenubar.h>
#include <qpopupmenu.h>
#include <qlayout.h>
#include <qftp.h>
#include <qthread.h>
#include <qwt_counter.h>
#include <qaction.h>
#include <qwhatsthis.h>
#include <qlabel.h>
#include <qwt_thermo.h>

#ifdef _WIN32
# include "../../Windows/moc/StationsDlgbase.h"
#else
# include "moc/StationsDlgbase.h"
#endif
#include "../DrmReceiver.h"
#include "../util/Vector.h"


/* Definitions ****************************************************************/
/* Define the timer interval of updating the list view */
#define GUI_TIMER_LIST_VIEW_STAT		30000 /* ms (30 seconds) */

/* Define the timer interval of updating the UTC label */
#define GUI_TIMER_UTC_TIME_LABEL		1000 /* ms (1 second) */

/* Define the timer interval of updating s-meter */
#define GUI_TIMER_S_METER				300 /* ms (0.3 seconds) */

/* s-meter thermo parameters */
#define S_METER_THERMO_MIN				((_REAL) -60.0) /* dB */
#define S_METER_THERMO_MAX				((_REAL) 60.0) /* dB */
#define S_METER_THERMO_ALARM			((_REAL) 0.0) /* dB */

/* Location of the newest DRM schedule ini-file "DRMSchedule.ini". This file
   is generated by Klaus Schneider which is the administrator of
   www.drm-dx.de */
#define DRM_SCHEDULE_UPDATE_FILE		"ftp://216.92.35.131/DRMSchedule.ini"

/* File handle type */
#ifdef _WIN32
# define FILE_HANDLE					HANDLE
#else
# define FILE_HANDLE					int
#endif

/* Name for DRM and AM schedule file. If you change something here, make sure
   that you also change the strings and help texts!  */
#define DRMSCHEDULE_INI_FILE_NAME		"DRMSchedule.ini"
#define AMSCHEDULE_INI_FILE_NAME		"AMSchedule.ini"

/* Time definitions for preview */
#define NUM_SECONDS_PREV_5MIN			300
#define NUM_SECONDS_PREV_15MIN			900
#define NUM_SECONDS_PREV_30MIN			1800

/* String definitions for schedule days */
#define FLAG_STR_IRREGULAR_TRANSM		"0000000"
#define CHR_ACTIVE_DAY_MARKER			'1'


/* Classes ********************************************************************/
class CStationsItem
{
public:
	CStationsItem() : iStartHour(0), iStartMinute(0), iStopHour(0), strName(""),
		iStopMinute(0), iFreq(0), strDaysFlags(""), strDaysShow(""),
		strTarget(""), strLanguage(""), strSite(""), strCountry(""),
		rPower((_REAL) 0.0) {}

	int GetStartTimeNum() {return iStartHour * 100 + iStartMinute;}
	int GetStopTimeNum() {return iStopHour * 100 + iStopMinute;}
	void SetStartTimeNum(const int iStartTime)
	{
		/* Recover hours and minutes */
		iStartHour = iStartTime / 100;
		iStartMinute = iStartTime - iStartHour * 100;
	}
	void SetStopTimeNum(const int iStopTime)
	{
		/* Recover hours and minutes */
		iStopHour = iStopTime / 100;
		iStopMinute = iStopTime - iStopHour * 100;
	}

	void SetDaysFlagString(const string strNewDaysFlags);

	int		iStartHour;
	int		iStartMinute;
	int		iStopHour;
	int		iStopMinute;
	int		iFreq;
	string	strName;
	string	strTarget;
	string	strLanguage;
	string	strSite;
	string	strCountry;
	string	strDaysFlags;
	string	strDaysShow;
	_REAL	rPower;
};


class CDRMSchedule
{
public:
	CDRMSchedule() {}
	virtual ~CDRMSchedule() {}

	enum ESchedMode {SM_DRM, SM_ANALOG};
	enum StationState {IS_ACTIVE, IS_INACTIVE, IS_PREVIEW};

	void ReadStatTabFromFile(const ESchedMode eNewSchM);
	ESchedMode GetSchedMode() {return eSchedMode;}

	int GetStationNumber() {return StationsTable.Size();}
	CStationsItem& GetItem(const int iPos) {return StationsTable[iPos];}
	StationState CheckState(const int iPos);

	void SetSecondsPreview(int iSec) {iSecondsPreview = iSec;}
	int GetSecondsPreview() {return iSecondsPreview;}

protected:
	_BOOLEAN IsActive(const int iPos, const time_t ltime);

	CVector<CStationsItem>	StationsTable;
	ESchedMode				eSchedMode;

	/* Minutes for stations preview in seconds if zero then no active */
    int						iSecondsPreview;
};


class MyListViewItem : public QListViewItem
{
public:
	MyListViewItem(QListView* parent, QString s1, QString s2 = QString::null,
		QString s3 = QString::null, QString s4 = QString::null,
		QString s5 = QString::null, QString s6 = QString::null,
		QString s7 = QString::null, QString s8 = QString::null) :
		QListViewItem(parent, s1, s2, s3, s4, s5, s6, s7, s8) {}

	/* Custom "key()" function for correct sorting behaviour */
	virtual QString key(int column, bool ascending) const;
};


class StationsDlg : public CStationsDlgBase
{
	Q_OBJECT

public:
	StationsDlg(CDRMReceiver* pNDRMR, QWidget* parent = 0,
		const char* name = 0, bool modal = FALSE, WFlags f = 0);
	virtual ~StationsDlg();

	void LoadSchedule(CDRMSchedule::ESchedMode eNewSchM);

protected:
	void			SetStationsView();
    virtual void	showEvent(QShowEvent* pEvent);
	void			AddWhatsThisHelp();
	void			SetUTCTimeLabel();
	void			EnableSMeter(const _BOOLEAN bStatus);

	CDRMReceiver*				pDRMRec;

	CDRMSchedule				DRMSchedule;
	QPixmap						BitmCubeGreen;
	QPixmap						BitmCubeYellow;
	QPixmap						BitmCubeRed;
	QPixmap						BitmCubeOrange;
	QTimer						TimerList;
	QTimer						TimerUTCLabel;
	QTimer						TimerSMeter;
	_BOOLEAN					bShowAll;
	QUrlOperator				UrlUpdateSchedule;
	QPopupMenu*					pViewMenu;
	QPopupMenu*					pPreviewMenu;

	CVector<MyListViewItem*>	vecpListItems;
	CMutex						ListItemsMutex;

	QPopupMenu*					pRemoteMenu;

	/* Com port selection */
	QAction*					pacMenuCOM1;
	QAction*					pacMenuCOM2;
	QAction*					pacMenuCOM3;
	QAction*					pacMenuCOM4;
	QAction*					pacMenuCOM5;
	QActionGroup*				agCOMPortSel;

#ifdef HAVE_LIBHAMLIB
	QPopupMenu*					pRemoteMenuOther;
	CVector<rig_model_t>		veciModelID;
#endif

public slots:
	void OnRemoteMenu(int iID);
	void OnComPortMenu(QAction* action);
	void OnSMeterMenu(int iID);
	void OnModRigMenu(int iID);
	void OnTimerList();
	void OnTimerUTCLabel() {SetUTCTimeLabel();}
	void OnTimerSMeter();
	void OnListItemClicked(QListViewItem* item);
	void OnUrlFinished(QNetworkOperation* pNetwOp);
	void OnShowStationsMenu(int iID);
	void OnShowPreviewMenu(int iID);
	void OnGetUpdate();
	void OnFreqCntNewValue(double dVal);
};
